#ifndef _ENTITY_H_
#define _ENTITY_H_

#ifdef _WIN32
#pragma once
#endif

// 03.03.12 - Steven Hartin - Fixed constructors not initialising constants
// 01.03.12 - Matthew Brews - Original Creation.

class CEntity;
class CMap;
class CPlayer;
class CMapContainer;

#include <string>

#include "displayable.h"

using std::string;

typedef enum entid
{
    // Basic Entities
    ENT_NONE = 0,
    ENT_PLAYER,
    ENT_PLAYER_SPAWN,
    ENT_PLAYER_1,
    ENT_PLAYER_2,
    ENT_PLAYER_3,
    ENT_PLAYER_4,
    ENT_PLAYER_5,
    ENT_PLAYER_6,
    ENT_PLAYER_7,
    ENT_PLAYER_8,
    
    
    // Tiles
    ENT_TILE_NONE = 0x80,
    ENT_TILE_SOLID,
    ENT_TILE_DESTRUCTIBLE,
    ENT_TILE_GRASS,
    ENT_TILE_CONCRETE,
    ENT_TILE_FREE,
    ENT_TILE_CONCRETE_2,
    ENT_TILE_DROPPABLE,
    ENT_TILE_DESERT_BOX,
    ENT_TILE_SANDSTONE_OUTSIDE,
    ENT_TILE_SANDSTONE,
    ENT_TILE_SAND,
    ENT_TILE_SNOW,
    ENT_TILE_SNOW_INSIDE,
    ENT_TILE_SNOW_OUTSIDE,
    ENT_TILE_SNOW_BOX,

    // Weapons
    ENT_WEAPON_NONE = 0x100,
    ENT_WEAPON_BOMB,

    // Pickups
    ENT_PICKUP_NONE = 0x180, 
    ENT_PICKUP_BOMB,
    ENT_PICKUP_POWER,
    ENT_PICKUP_SPEED,
    ENT_PICKUP_BOMB_DOWN,
    ENT_PICKUP_POWER_DOWN,
    ENT_PICKUP_SPEED_DOWN,

    // Buffs
    ENT_BUFF_NONE = 0x200,
    ENT_BUFF_SPEED,
    ENT_BUFF_BOMB,
    ENT_BUFF_POWER,
    ENT_DEBUFF_SPEED,
    ENT_DEBUFF_BOMB,
    ENT_DEBUFF_POWER,

    // Projectiles
    ENT_PROJECTILE_BOMB = 0x280


} ENTITY_ID;

typedef struct st_attatchable
{
    CEntity *pEntity;
    float fXOffset;
    float fYOffset;
    float fZOffset;
} st_attatchable;

class CEntity
{
public:
    CEntity(const string &szKey, const ENTITY_ID &nId, float y, float x, 
            float z, bool visible);
    CEntity(const ENTITY_ID &nId, float y, float x, float z, bool visible);
    virtual ~CEntity();

    bool getVisible() const;
    void setVisible(bool bVisible);
    virtual void destroy();
    CDisplayable *getDisplayable() const;
    void setDisplayable(CDisplayable *pDisplayable);
    string getKey() const;
    ENTITY_ID getID() const;

    ENTITY_ID getSubID() const;
    void setSubID(const ENTITY_ID &nId);

    virtual void onCreate(CMap *pMap) {}
    virtual void onDestroy() {}

    virtual void setPosition(float x, float y, float z);
    virtual void setX(float x);
    virtual void setY(float y);
    virtual void setZ(float z);
    void getPosition(float &fx, float &fy, float &fz);
    float getX() const;
    float getY() const;
    float getZ() const;

    CEntity *getOwner() const;
    void setOwner(CEntity *pEntity);

    void attachEntity(CEntity *pEntity, float fXOffset, float fYOffset,
                       float fZOffset);
    void detachEntity(CEntity *pEntity);
    bool isAttached(CEntity *pEntity);

    void render() const;
    virtual void tick() {}

    bool isCollectible() const;
    void setCollectible(bool bCollectable);
    virtual void collect(CPlayer *pPlayer) {}

    void setDirtyBit();
    bool getDirtyBit();

    virtual void reset() {}

    bool isPermanent() const;
    void setPermanent(bool bPermanent);

private:

    // Permanent will mean will it will persist on reset. 
    bool m_bPermanent;

    bool m_bCollectible;

    const ENTITY_ID m_nId;
    ENTITY_ID m_nSubId;
    const string m_szKey;
    CDisplayable *m_pDisplayable;

    vector<st_attatchable> m_arrAttachments;

    CEntity *m_pOwner;

    float m_fX, m_fY, m_fZ;
    bool m_bVisible;
    bool m_bDirtyBit;
};



#endif
